package com.suma.android.activity;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;

import com.suma.android.util.VideoConfig;
import com.suma.android.util.VideoConfig.PushUrl;

public class PlayerActivity extends Activity implements OnCompletionListener,
		MediaPlayer.OnPreparedListener, MediaPlayer.OnSeekCompleteListener,
		MediaPlayer.OnErrorListener, SurfaceHolder.Callback,
		SeekBar.OnSeekBarChangeListener {
	// 控件
	private SurfaceView view;
	private MediaPlayer player;
	private ImageButton btnPlay;
	private Button btnPad;
	private Button btnMobile;
	private Button btnPC;
	private Button btnStb;
	private SeekBar seekBar;
	private TextView timelength;
	private TextView push;
	private TextView message;
	private ProgressDialog dialog;
	// 定时器
	private Handler handler;
	private Runnable updateProgress;
	// 全局变量

	private VideoConfig config = null;
	private int position = 0; // position=-1时表示player出异常，不再记录断点

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_player);
		view = (SurfaceView) findViewById(R.id.view);
		view.requestFocus();
		Intent intent = getIntent();
		config = (VideoConfig)intent.getSerializableExtra("url");
		// 初始化控件对象
		btnPlay = (ImageButton) findViewById(R.id.btn_play);
		btnMobile = (Button) findViewById(R.id.btn_mobile);
		btnPad = (Button) findViewById(R.id.btn_pad);
		btnPC = (Button) findViewById(R.id.btn_pc);
		btnStb = (Button) findViewById(R.id.btn_stb);
		seekBar = (SeekBar) findViewById(R.id.progress);
		timelength = (TextView) findViewById(R.id.timelength);
		push = (TextView) findViewById(R.id.push);
		message = (TextView) findViewById(R.id.message);
		if (config.isLive()) {
			seekBar.setEnabled(false);
		}

		SurfaceHolder holder = view.getHolder();
		holder.addCallback(this);
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		player = new MediaPlayer();
		player.setWakeMode(this.getApplicationContext(),
				PowerManager.FULL_WAKE_LOCK);
		player.setOnPreparedListener(this);
		player.setOnCompletionListener(this);
		player.setOnErrorListener(this);
		player.setDisplay(holder);

		// 注册监听
		ClickListener btnListener = new ClickListener();
		btnPlay.setOnClickListener(btnListener);
		btnStb.setOnClickListener(btnListener);
		btnPC.setOnClickListener(btnListener);
		btnPad.setOnClickListener(btnListener);
		btnMobile.setOnClickListener(btnListener);
		seekBar.setOnSeekBarChangeListener(this);

		// 定时器初始化
		handler = new Handler();
		updateProgress = new Runnable() {
			@Override
			public void run() {
				seekBar.setProgress(player.getCurrentPosition());
				handler.postDelayed(updateProgress, 1000);
			}
		};
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (player != null) {
			player.release();
			player = null;
		}
		handler.removeCallbacks(updateProgress);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			if (btnPlay.getVisibility() == View.INVISIBLE) {
				setControlVisible(true);
			} else {
				setControlVisible(false);
			}
		}
		return super.onTouchEvent(event);
	}

	@Override
	public void onPrepared(MediaPlayer mp) {
		dialog.dismiss();
		seekBar.setProgress(0);
		seekBar.setMax(mp.getDuration());
		timelength.setText(toDate(0) + "/" + toDate(mp.getDuration()));
		mp.start();
	}

	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		exitWithAlert(R.string.error_end, true);
		return false;
	}

	@Override
	public void onSeekComplete(MediaPlayer mp) {
		mp.start();
	}

	@Override
	public void onCompletion(MediaPlayer mp) {
		player.release();
		handler.removeCallbacks(updateProgress);
		exitWithAlert(R.string.error_end, false);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		try {
			player.reset();
			player.setDataSource(config.getUrl());
			player.setAudioStreamType(AudioManager.STREAM_MUSIC);
			if (position > 0) {
				player.prepare();
				player.seekTo(position);
				position = 0;
			} else {
				dialog = ProgressDialog.show(PlayerActivity.this, "",
						getString(R.string.title_loading), true);
				player.prepareAsync();
			}
		} catch (Exception e) {
			exitWithAlert(R.string.error_url_invalid, true);
		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		if (position != -1 && player.isPlaying()) {
			position = player.getCurrentPosition();
			player.stop();
		}
	}

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress,
			boolean fromUser) {
		if (fromUser) {
			player.seekTo(progress);
		}
		timelength.setText(toDate(progress) + "/"
				+ toDate(player.getDuration()));
	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {
	}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
	}

	private class ClickListener implements View.OnClickListener {
		@Override
		public void onClick(View v) {
			PushUrl purl =  config.getPushurl();
			String httpurl = null;
			
			switch (v.getId()) {
			case R.id.btn_play:
				if (player.isPlaying()) {
					player.pause();
					btnPlay.setImageResource(R.drawable.play);
				} else {
					player.start();
					btnPlay.setImageResource(R.drawable.pause);
				}
				break;
			case R.id.btn_mobile:
				httpurl = purl.getMobile();
				break;
			case R.id.btn_pad:
				httpurl = purl.getPad();
				break;
			case R.id.btn_pc:
				httpurl = purl.getPc();
				break;
			case R.id.btn_stb:
				httpurl = purl.getStb();
				break;
			default:
				break;
			}
			// 发送推送请求
			if (httpurl != null && !"".equals(httpurl)) {
				new HttpRequest().execute(httpurl);
			}
		}
	}

	private void setControlVisible(boolean b) {
		if (b) {
			btnPlay.setVisibility(View.VISIBLE);
			seekBar.setVisibility(View.VISIBLE);
			timelength.setVisibility(View.VISIBLE);
			
			PushUrl purl =  config.getPushurl();
			if (purl != null) {
				if (purl.getStb() != null && !"".equals(purl.getStb()))
					btnStb.setVisibility(View.VISIBLE);
				if (purl.getPc() != null && !"".equals(purl.getPc()))
					btnPC.setVisibility(View.VISIBLE);
				if (purl.getPad() != null && !"".equals(purl.getPad()))
					btnPad.setVisibility(View.VISIBLE);
				if (purl.getMobile() != null && !"".equals(purl.getMobile()))
					btnMobile.setVisibility(View.VISIBLE);
				push.setVisibility(View.VISIBLE);
			}
			handler.post(updateProgress);
		} else {
			btnPlay.setVisibility(View.INVISIBLE);
			seekBar.setVisibility(View.INVISIBLE);
			timelength.setVisibility(View.INVISIBLE);
			btnStb.setVisibility(View.GONE);
			btnPC.setVisibility(View.GONE);
			btnPad.setVisibility(View.GONE);
			btnMobile.setVisibility(View.GONE);
			push.setVisibility(View.INVISIBLE);
			handler.removeCallbacks(updateProgress);
		}
	}

	private String toDate(int milliseconds) {
		int seconds = milliseconds / 1000;
		int minute = seconds / 60;
		seconds = seconds % 60;
		String time = minute < 10 ? "0" + minute + ":" : minute + ":";
		time += seconds < 10 ? "0" + seconds : seconds;
		return time;
	}

	private void exitWithAlert(int msg, boolean showUrl) {
		position = -1;
		player.release();
		handler.removeCallbacks(updateProgress);
		if (showUrl) {
			message.setText(config.getUrl());
			message.setVisibility(View.VISIBLE);
		}
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setMessage(msg)
				.setCancelable(false)
				.setPositiveButton(R.string.confirm,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								PlayerActivity.this.finish();
							}
						});
		AlertDialog alert = builder.create();
		alert.show();
	}
	
	private class HttpRequest extends AsyncTask<String, Void, String> {
		@Override
		protected String doInBackground(String... params) {
			String result = "";
			if (params != null && params.length > 0) {
				HttpGet httpget = new HttpGet(params[0]);
				HttpClient client = new DefaultHttpClient();
				try {
					HttpResponse response = client.execute(httpget);
					if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
						String msg = EntityUtils.toString(response.getEntity(),
								"utf-8");
						JSONArray json = new JSONArray(msg);
						String code = json.getJSONObject(0).getString(
								"errorCode");
						String info = json.getJSONObject(0).getString(
								"errorInfo");
						if ("200".equals(code)) {
							result = getString(R.string.push_success);
						} else {
							result = code + "," + info;
						}
					} else {
						result = getString(R.string.error_http_status_invalid);
					}
				} catch (Exception e) {
					result = getString(R.string.error_push) + e.getMessage();
				}
			}
			return result;
		}

		@Override
		protected void onPostExecute(String result) {
			if (result != null && !"".equals(result)) {
				AlertDialog.Builder builder = new AlertDialog.Builder(
						PlayerActivity.this);
				builder.setMessage(result)
						.setCancelable(false)
						.setPositiveButton(R.string.confirm,
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int id) {
										dialog.dismiss();
									}
								});
				AlertDialog alert = builder.create();
				alert.show();
			}
			super.onPostExecute(result);
		}
	}

}
